#include "IOFile.h"
#include "include/PowerLibraryEngine.h"
#include "FileSystem.h"
#include "Config.h"

CIOFile::CIOFile(stringc dir,stringc filename,CFileSystem *fsp):Buffer(NULL),fs(fsp)
{
	fd.DirOnly = dir;
	fd.FileNameOnly = filename;
	fd.CompleteName = dir + filename;
}

CIOFile::~CIOFile()
{
	DEALLOCATEARRAY(Buffer);
	FileList.DeleteListNodes();
}

void CIOFile::AddChild(CIOFile *newChild)
{
	FileList.push_back(newChild);
}

void CIOFile::CreateChildTree()
{
	FindDataStrc fds;
	bool hFile;
	bool done=false;
	stringc AbsolutePath = fd.CompleteName;

	AbsolutePath = ConvertToDir(AbsolutePath);

#ifdef __COMPILE_WIN32__
	stringc Path = AbsolutePath + "*.*";
#else
    stringc Path = AbsolutePath;
#endif

	pLogDebug << "CIOFile:: Entering directory " << AbsolutePath << endl;

	hFile =  FindFirst(Path,&fds);

	if (hFile)
	{
		while(!done)
		{
			if (fds.Name != "." && fds.Name != "..")
			{
				stringc FileName = AbsolutePath + fds.Name;
				CIOFile *newFile = fs->GetNewCIOFile(AbsolutePath,fds.Name);
				newFile->fd.CompleteName = FileName;
				newFile->fd.FileNameOnly = fds.Name;
				newFile->fd.Size = fds.Size;
				newFile->fd.PointerToFile = fds.PointerToFile;
				newFile->fd.IsLoaded = false;

				AddChild(newFile);

				if (newFile->IsSubDir(&fds))
				{
					newFile->fd.IsDirectory = true;
					newFile->CreateChildTree();
					pLogDebug << "CIOFile:: Going back to directory " << AbsolutePath << endl;
				}
				else
				{
					pLogDebug << "CIOFile:: Found file" << newFile->fd.FileNameOnly << " with size:" << newFile->fd.Size << endl;
					newFile->fd.IsDirectory = false;
				}
			}

			done = FindNext(&fds);
		}
	}

	FindClose();
}

CIOFile *CIOFile::Search(stringc Name)
{
	if (fd.FileNameOnly == Name)
		return this;

	if (fd.IsDirectory)
	{
		for (FileListType::iterator it = FileList.begin();it!=FileList.end();it++)
		{
			CIOFile *Temp = (*it)->Search(Name);
			if (Temp)
				return Temp;
		}
	}

	return NULL;
}

bool CIOFile::LoadEntireFile()
{
	u32 Result = CopyFromFileToMemory(fd.Size);
	bool GoodWork = (Result == fd.Size);

	return GoodWork;
}

IIOFile *CIOFile::GetFileByIndex(u32 Index)
{
	u32 Actual=0;
	for (FileListType::iterator it=FileList.begin();it!=FileList.end();it++)
	{
		if (Actual==Index)
			return (*it);
		Actual++;
	}

	return NULL;
}

u32 CIOFile::GetNumElements()
{
	return FileList.size();
}

bool CIOFile::IsDirectoryString(stringc Dir)
{
	if (Dir.size() > 0)
		return (Dir[Dir.size()-1] == DIR_SEPARATOR_CHAR);
	else
		return false;

}

stringc CIOFile::ConvertToDir(stringc Dir)
{
	stringc Temp = Dir;
	if (!IsDirectoryString(Temp))
		Temp = Temp + DIR_SEPARATOR_CHAR;

	return Temp;
}
